package spacewar2.clients;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

import spacewar2.actions.DoNothingAction;
import spacewar2.actions.MoveAction;
import spacewar2.actions.SpacewarAction;
import spacewar2.actions.SpacewarPurchaseEnum;
import spacewar2.objects.Ship;
import spacewar2.objects.SpacewarActionableObject;
import spacewar2.objects.SpacewarObject;
import spacewar2.powerups.SpacewarPowerup;
import spacewar2.shadows.CircleShadow;
import spacewar2.shadows.Shadow;
import spacewar2.simulator.Toroidal2DPhysics;
import spacewar2.utilities.Position;

public class RandomTeamClient extends TeamClient {
	HashSet<Shadow> newShadows;
	HashSet<Shadow> oldShadows;
	HashMap<Ship, Shadow> currentShadows;
	Random random;
	boolean fired = false;
	
	public static int RANDOM_MOVE_RADIUS = 200;
	public static double SHOOT_PROBABILITY = 0.1;
	
	@Override
	public void initialize() {
		newShadows = new HashSet<Shadow>();
		oldShadows = new HashSet<Shadow>();
		currentShadows = new HashMap<Ship,Shadow>();
		random = new Random();
	}

	@Override
	public void shutDown() {
		// TODO Auto-generated method stub

	}


	@Override
	public Map<UUID, SpacewarAction> getMovementStart(Toroidal2DPhysics space,
			Set<SpacewarActionableObject> actionableObjects) {
		HashMap<UUID, SpacewarAction> randomActions = new HashMap<UUID, SpacewarAction>();
		
		for (SpacewarObject actionable :  actionableObjects) {
			if (actionable instanceof Ship) {
				Ship ship = (Ship) actionable;
				SpacewarAction current = ship.getCurrentAction();
				
				// if we finished, add it to the old shadows (so it gets removed)
				if (current != null && current.isMovementFinished(space)) {
					oldShadows.add(currentShadows.get(ship));
				}
				
			
				// if we finished, make a new spot in space to aim for
				if (current == null || current.isMovementFinished(space)) {
					Position currentPosition = ship.getPosition();
					Position newGoal = space.getRandomFreeLocationInRegion(random, Ship.SHIP_RADIUS, (int) currentPosition.getX(), 
							(int) currentPosition.getY(), RANDOM_MOVE_RADIUS);
					MoveAction newAction = null;
					newAction = new MoveAction(space, currentPosition, newGoal);
					//System.out.println("Ship is at " + currentPosition + " and goal is " + newGoal);
					Shadow shadow = new CircleShadow(1, getTeamColor(), newGoal);
					newShadows.add(shadow);
					currentShadows.put(ship, shadow);
					//Vector2D shortVec = space.findShortestDistanceVector(currentPosition, newGoal);
					//LineShadow lineShadow = new LineShadow(currentPosition, newGoal, shortVec);
					//newShadows.add(lineShadow);
					randomActions.put(ship.getId(), newAction);
				} else {
					randomActions.put(ship.getId(), ship.getCurrentAction());
				}
				
			} else {
				// it is a base and random doesn't do anything to bases
				randomActions.put(actionable.getId(), new DoNothingAction());
		}
			

		}
	
		return randomActions;
	
	}


	@Override
	public void getMovementEnd(Toroidal2DPhysics space, Set<SpacewarActionableObject> actionableObjects) {
		newShadows.clear();
	}

	@Override
	public Set<Shadow> getNewShadows() {
		return newShadows;
	}

	@Override
	public Set<Shadow> getOldShadows() {
		if (oldShadows.size() > 0) {
			Set<Shadow> shadows = new HashSet<Shadow>(oldShadows);
			oldShadows.clear();
			return shadows;
		} else {
			return null;
		}
	}

	@Override
	/**
	 * Random never purchases 
	 */
	public Map<UUID, SpacewarPurchaseEnum> getTeamPurchases(Toroidal2DPhysics space,
			Set<Ship> ships, int availableMoney, int currentCostNewBase) {
		return new HashMap<UUID,SpacewarPurchaseEnum>();

	}

	/**
	 * This is the new way to shoot (and use any other power up once they exist)
	 */
	public Map<UUID, SpacewarPowerup> getPowerups(Toroidal2DPhysics space,
			Set<SpacewarActionableObject> actionableObjects) {
		
		HashMap<UUID, SpacewarPowerup> powerupMap = new HashMap<UUID, SpacewarPowerup>();
		
		for (SpacewarObject actionable :  actionableObjects) {
			if (actionable instanceof Ship) {
				Ship ship = (Ship) actionable;
				if (random.nextDouble() < SHOOT_PROBABILITY) {
					powerupMap.put(ship.getId(), ship.getNewBullet());
					//System.out.println("Firing!");
				}
			}
		}
		return powerupMap;
	}


}
